package org.gikolet.ch2.android;

import org.gikolet.ch2.android.dao.AndroidBoardsDao;
import org.gikolet.ch2.android.dao.AndroidThreadHeaderDao;
import org.gikolet.ch2.android.dao.AndroidTransactionManager;
import org.gikolet.ch2.android.dao.SQLiteDatabaseProvider;
import org.gikolet.ch2.android.logic.AndroidBoardsLogic;
import org.gikolet.ch2.android.logic.AndroidResesLogic;
import org.gikolet.ch2.android.logic.AndroidThreadHeadersLogic;
import org.gikolet.ch2.android.viewer.BoardsViewer;
import org.gikolet.ch2.android.viewer.ResesViewer;
import org.gikolet.ch2.android.viewer.ThreadHeadersViewer;
import org.gikolet.ch2.android.viewer.Viewer;
import org.gikolet.ch2.android.widget.BoardsAdapter;
import org.gikolet.ch2.android.widget.ResListView;
import org.gikolet.ch2.android.widget.ThreadHeaderAdapter;
import org.gikolet.ch2.dao.BoardsDao;
import org.gikolet.ch2.dao.ThreadHeaderDao;
import org.gikolet.ch2.io.BoardsReaderProvider;
import org.gikolet.ch2.io.ResesReaderProvider;
import org.gikolet.ch2.io.Storage;
import org.gikolet.ch2.io.ThreadHeadersReaderProvider;
import org.gikolet.ch2.logic.BoardsLogic;
import org.gikolet.ch2.logic.ResesLogic;
import org.gikolet.ch2.logic.ThreadHeadersLogic;
import org.gikolet.guice.db.TransactionManager;
import org.gikolet.guice.db.TransactionObject;
import org.gikolet.guice.db.TransactionProvider;

import android.database.sqlite.SQLiteDatabase;

import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;

public class GikoletModule implements Module {

	public void configure(Binder b) {
		b.bindConstant().annotatedWith(Names.named("sharedPreferencesContext"))
				.to("org.gikolet.android");

		b.bind(int.class).annotatedWith(
				Names.named(BoardsAdapter.BOARDS_LAYOUT_ID)).toInstance(
				R.layout.boards);
		b.bind(int.class).annotatedWith(
				Names.named(BoardsAdapter.CATEGORY_TEXT_VIEW_ID)).toInstance(
				R.id.board_category);
		b.bind(int.class).annotatedWith(
				Names.named(BoardsAdapter.BOARD_TEXT_VIEW_ID)).toInstance(
				R.id.board_name);

		b.bind(int.class).annotatedWith(
				Names.named(ThreadHeaderAdapter.SUBJECTS_LAYOUT_ID))
				.toInstance(R.layout.subjects);
		b.bind(int.class).annotatedWith(
				Names.named(ThreadHeaderAdapter.SUBJECT_DATE_VIEW_ID))
				.toInstance(R.id.SubjectDate);
		b.bind(int.class).annotatedWith(
				Names.named(ThreadHeaderAdapter.SUBJECT_RES_COUNT_VIEW_ID))
				.toInstance(R.id.SubjectResCount);
		b.bind(int.class).annotatedWith(
				Names.named(ThreadHeaderAdapter.SUBJECT_TEXT_VIEW_ID))
				.toInstance(R.id.SubjectText);

		b.bind(Storage.class).to(GikoletBbsProvider.class);

		// DAOの設定
		b.bind(BoardsDao.class).to(AndroidBoardsDao.class);
		b.bind(ThreadHeaderDao.class).to(AndroidThreadHeaderDao.class);

		// トランザクションの設定
		b.bind(SQLiteDatabase.class).toProvider(SQLiteDatabaseProvider.class);
		b.bind(TransactionManager.class).to(AndroidTransactionManager.class);

		// ロジックの設定
		b.bind(BoardsLogic.class).annotatedWith(TransactionObject.class).to(
				AndroidBoardsLogic.class);
		b.bind(BoardsLogic.class).toProvider(
				Key.get(new TypeLiteral<TransactionProvider<BoardsLogic>>() {
				}));
		b.bind(ThreadHeadersLogic.class).annotatedWith(TransactionObject.class)
				.to(AndroidThreadHeadersLogic.class);
		b
				.bind(ThreadHeadersLogic.class)
				.toProvider(
						Key
								.get(new TypeLiteral<TransactionProvider<ThreadHeadersLogic>>() {
								}));
		b.bind(ResesLogic.class).annotatedWith(TransactionObject.class).to(
				AndroidResesLogic.class);
		b.bind(ResesLogic.class).toProvider(
				Key.get(new TypeLiteral<TransactionProvider<ResesLogic>>() {
				}));

		b.bind(BoardsAdapter.class);

		b.bind(Viewer.class).annotatedWith(
				Names.named(BoardsViewer.class.getName())).to(
				BoardsViewer.class);
		b.bind(Viewer.class).annotatedWith(
				Names.named(ThreadHeadersViewer.class.getName())).to(
				ThreadHeadersViewer.class);
		b.bind(Viewer.class).annotatedWith(
				Names.named(ResesViewer.class.getName())).to(ResesViewer.class);

		b.bind(BoardsReaderProvider.class).to(GikoletBbsProvider.class);
		b.bind(ThreadHeadersReaderProvider.class).to(GikoletBbsProvider.class);
		b.bind(ResesReaderProvider.class).to(GikoletBbsProvider.class);

		// ちょっとView
		b.bind(ResListView.class);
		b.bind(int.class).annotatedWith(
				Names.named(ResListView.RES_LIST_VIEW_LAYOUT_ID)).toInstance(
				R.layout.reses);
		b.bind(int.class).annotatedWith(
				Names.named(ResListView.RES_LIST_VIEW_ID)).toInstance(R.id.res);
	}
}
